repo: When writing to a non-root owned repo, chown() objects to match
authorColin Walters <walters@verbum.org>
Tue, 21 Oct 2014 18:34:04 +0000 (14:34 -0400)
committerColin Walters <walters@verbum.org>
Tue, 21 Oct 2014 19:43:43 +0000 (15:43 -0400)
Some package systems need to be run as root, so the process linking to
libostree may also be root.  However, it's reasonable to have the
target repository be owned by a uid other than root.

This patch makes it Just Work by chowning the file content to match.

Note this only operates on archive-z2 repositories, because you can't
usefully serve bare repositories via HTTP.

https://bugzilla.gnome.org/show_bug.cgi?id=738954

src/libostree/ostree-repo-commit.c
src/libostree/ostree-repo-private.h
src/libostree/ostree-repo.c

index 68cff05d4d730500338cbe84617693504683d70f..f76dcd66f41b9db2807c5573be49d3e74db4b61b 100644 (file)
@@ -72,6 +72,22 @@ commit_loose_object_trusted (OstreeRepo        *self,
 {
   gboolean ret = FALSE;
 
+  /* We may be writing as root to a non-root-owned repository; if so,
+   * automatically inherit the non-root ownership.
+   */
+  if (self->mode == OSTREE_REPO_MODE_ARCHIVE_Z2
+      && self->target_owner_uid != -1) 
+    {
+      if (G_UNLIKELY (fchownat (self->tmp_dir_fd, temp_filename,
+                                self->target_owner_uid,
+                                self->target_owner_gid,
+                                AT_SYMLINK_NOFOLLOW) == -1))
+        {
+          ot_util_set_error_from_errno (error, errno);
+          goto out;
+        }
+    }
+
   /* Special handling for symlinks in bare repositories */
   if (is_symlink && self->mode == OSTREE_REPO_MODE_BARE)
     {
index ad512f986c21185667ab99e8acc2f55f0d2b7203..e893c4f8650fe0ad0bff8da52173dd0db22e65f1 100644 (file)
@@ -65,6 +65,9 @@ struct OstreeRepo {
   GHashTable *updated_uncompressed_dirs;
   GHashTable *object_sizes;
 
+  uid_t target_owner_uid;
+  gid_t target_owner_gid;
+
   GKeyFile *config;
   OstreeRepoMode mode;
   gboolean enable_uncompressed_cache;
index 4887e8d15688ce356e6531b781084a4f45859e1f..98617552fd91d53c61a9519ab87a0a68e304ea0d 100644 (file)
@@ -819,6 +819,7 @@ ostree_repo_open (OstreeRepo    *self,
 {
   gboolean ret = FALSE;
   gboolean is_archive;
+  struct stat stbuf;
   gs_free char *version = NULL;
   gs_free char *mode = NULL;
   gs_free char *parent_repo_path = NULL;
@@ -836,6 +837,22 @@ ostree_repo_open (OstreeRepo    *self,
 
   self->writable = faccessat (AT_FDCWD, gs_file_get_path_cached (self->objects_dir), W_OK, 0) == 0;
 
+  if (fstat (self->objects_dir_fd, &stbuf) != 0)
+    {
+      ot_util_set_error_from_errno (error, errno);
+      goto out;
+    }
+
+  if (stbuf.st_uid != getuid () || stbuf.st_gid != getgid ())
+    {
+      self->target_owner_uid = stbuf.st_uid;
+      self->target_owner_gid = stbuf.st_gid;
+    }
+  else
+    {
+      self->target_owner_uid = self->target_owner_gid = -1;
+    }
+
   self->config = g_key_file_new ();
   if (!g_key_file_load_from_file (self->config, gs_file_get_path_cached (self->config_file), 0, error))
     {